#ifndef PropertyImp_h
#define PropertyImp_h

#include "Property.h"

namespace hxe
{
    class BoolProperty : public Property
    {
    public:
        bool boolValue;

        virtual bool getBool() { return boolValue; }

        virtual int getInt() { return boolValue ? 1 : 0; }

        virtual float getFloat() { return boolValue ? 1.0f : 0.0f; }

        virtual void setBool(bool value) { boolValue = value; }

        virtual void setInt(int value) { boolValue = value != 0; }

        virtual void setFloat(float value) { boolValue = value != 0.0f; }

        BoolProperty(std::string name) :Property(name) { setBool(false); }

        virtual PropertyType getPropertyType() const { return PROPERTY_BOOL; }

        virtual Property* copy() 
        {
            Property* p = new BoolProperty(getName());
            p->setBool(this->getBool());
            return p;
        }
    };

    class IntProperty : public Property
    {
    public:
        int intValue;

        virtual bool getBool() { return intValue != 0; }

        virtual int getInt() { return intValue; }

        virtual float getFloat() 
        {
            return (float)intValue;
        }

        virtual void setBool(bool value) { intValue = (int)value; }

        virtual void setInt(int value) { intValue = value; }

        virtual void setFloat(float value) { intValue = (int)value; }

        IntProperty(std::string name) :Property(name) { setInt(0); }

        virtual PropertyType getPropertyType() const { return PROPERTY_INT; }

        virtual Property* copy()
        {
            Property* p = new IntProperty(getName());
            p->setInt(this->getInt());
            return p;
        }
    };

    class FloatProperty : public Property
    {
    public:
        float floatValue;

        virtual bool getBool() { return floatValue != 0.0f; }

        virtual int getInt() { return (int)floatValue; }

        virtual float getFloat()
        {
            return floatValue;
        }

        virtual void setBool(bool value) { floatValue = (float)value; }

        virtual void setInt(int value) { floatValue = (float)value; }

        virtual void setFloat(float value) { floatValue = value; }

        FloatProperty(std::string name) :Property(name) { setFloat(0.0f); }

        virtual PropertyType getPropertyType() const { return PROPERTY_FLOAT; }

        virtual Property* copy()
        {
            Property* p = new FloatProperty(getName());
            p->setFloat(this->getFloat());
            return p;
        }
    };

    class Vector3Property : public Property
    {
    public:
        Vector3 vector3Value;

        virtual Vector3 getVector3() { return vector3Value; }

        virtual Vector4 getVector4() { return Vector4(vector3Value.x, vector3Value.y, vector3Value.z, 0.0f); }

        virtual void setVector3(Vector3 value) { vector3Value = value; }

        virtual void setVector4(Vector4 value) { vector3Value = value; }

        Vector3Property(std::string name) :Property(name) { setVector3(Vector3(0.0f, 0.0f, 0.0f)); }

        virtual PropertyType getPropertyType() const { return PROPERTY_VECTOR_3; }

        virtual Property* copy()
        {
            Property* p = new Vector3Property(getName());
            p->setVector3(this->getVector3());
            return p;
        }
    };

    class Vector4Property : public Property
    {
    public:
        Vector4 vector4Value;

        virtual Vector3 getVector3() { return vector4Value; }

        virtual Vector4 getVector4() { return vector4Value; }

        virtual void setVector3(Vector3 value) { vector4Value = Vector4(value.x, value.y, value.z, 0.0f); }

        virtual void setVector4(Vector4 value) { vector4Value = value; }

        Vector4Property(std::string name) :Property(name) { setVector4(Vector4(0.0f, 0.0f, 0.0f, 0.0f)); }

        virtual PropertyType getPropertyType() const { return PROPERTY_VECTOR_4; }

        virtual Property* copy()
        {
            Property* p = new Vector4Property(getName());
            p->setVector4(this->getVector4());
            return p;
        }
    };

    class Matrix4x4Property : public Property
    {
    public:
        Matrix4x4 vector4Value;

        virtual Matrix4x4 getMatrix() { return vector4Value; }

        virtual void setMatrix(Matrix4x4 value) { vector4Value = value; }

        Matrix4x4Property(std::string name) :Property(name) { setMatrix(Matrix4x4(1.0f)); }

        virtual PropertyType getPropertyType() const { return PROPERTY_MATRIX_4X4; }

        virtual Property* copy()
        {
            Property* p = new Matrix4x4Property(getName());
            p->setMatrix(this->getMatrix());
            return p;
        }
    };
}

#endif // PropertyImp_h
